<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en-US">
<head>
    <meta charset="utf-8">


    <link href="/assets/css/all.css" rel="stylesheet" type="text/css">
    <script async src="/assets/js/all.js"></script>


    <script type="text/x-mathjax-config">
      MathJax.Hub.Config({tex2jax: {inlineMath: [['«', '»']]}});
      MathJax.Hub.config.tex2jax.skipTags = ["script", "noscript", "style", "textarea", "annotation", "annotation-xml"];

    </script>
    <script async src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-AMS_HTML'></script>
    <!-- Google Analytics -->
    <script>
        window.ga = window.ga || function () {
            (ga.q = ga.q || []).push(arguments)
        };
        ga.l = +new Date;
        ga('create', 'UA-58002512-1', 'auto');
        ga('set', 'anonymizeIp', true);
        ga('send', 'pageview');
    </script>
    <script async src='https://www.google-analytics.com/analytics.js'></script>
    <!-- End Google Analytics -->

    <title>Nim by Example - Enums</title>

    <meta content="nanoc 4.9.9" name="generator">
    <meta content="colorful" http-equiv="Default-Style">
    <meta content="width=device-width, initial-scale=1" name=viewport>
</head>
<body>

<div id="sidebar">
    <div class="abs-hamburger">
        <div class="nav-toggle" onclick="sidebarClick();"><span></span></div>
    </div>
    <nav>
        <ul>
            <li><a href="/getting_started/">Getting Started</a></li>
            <li><a href="/hello_world/">Hello World</a></li>
            <li><a href="/comments/">Comments</a></li>
            <li><a href="/variables/">Variables</a>
                <ul>
                    <li><a href="/variables/result/">Result</a></li>
                    <li><a href="/variables/type_casting_inference/">Type Casting and Inference</a></li>
                </ul>
            </li>
            <li><a href="/if_else_while/">If, Else, While</a></li>
            <li><a href="/case/">Case Statements</a></li>
            <li><a href="/for_iterators/">For Loops &amp; Iterators</a></li>
            <li><a href="/procs/">Procs</a></li>
            <li><a href="/procvars/">First Class Functions</a></li>
            <li><a href="/block/">Blocks</a></li>
            <li><a href="/primitives/">Primitive Types</a></li>
            <li><a href="/types/">Type Aliases</a></li>
            <li><a href="/types/objects/">Object Types</a></li>
            <li><a href="/types/enums/">Enum Types</a></li>
            <li><a href="/types/distinct/">Distinct Types</a></li>
            <li><a href="/strings/">Strings</a></li>
            <li><a href="/arrays/">Arrays</a></li>
            <li><a href="/seqs/">Seqs</a></li>
            <li><a href="/bitsets/">Bitsets</a></li>
            <li><a href="/files/">Files</a></li>
            <li><a href="/json/">JSON</a></li>
            <li><a href="/varargs/">Varargs</a></li>
            <li><a href="/oop/">Object Oriented Programming</a></li>
            <li><a href="/macros/">Macros</a></li>
        </ul>


    </nav>
</div>

<article>
    <h1 id="enums">Enums</h1>
    <p>Enums in Nim are like enums in C, but are type-checked. There are no anonymous enums in Nim.</p>

    <pre><code class="language-nimrod"><span class="k">type</span>
  <span class="n">CompassDirections</span> <span class="o">=</span> <span class="k">enum</span>
    <span class="n">cdNorth</span><span class="p">,</span> <span class="n">cdEast</span><span class="p">,</span> <span
                class="n">cdSouth</span><span class="p">,</span> <span class="n">cdWest</span>

  <span class="n">Colors</span> <span class="p">{.</span><span class="n">pure</span><span class="p">.}</span> <span
                class="o">=</span> <span class="k">enum</span>
    <span class="n">Red</span> <span class="o">=</span> <span class="s">"FF0000"</span><span class="p">,</span> <span
                class="n">Green</span> <span class="o">=</span> <span class="p">(</span><span class="mi">1</span><span
                class="p">,</span> <span class="s">"00FF00"</span><span class="p">),</span> <span class="n">Blue</span> <span
                class="o">=</span> <span class="s">"0000FF"</span>

  <span class="n">OtherColors</span> <span class="p">{.</span><span class="n">pure</span><span class="p">.}</span> <span
                class="o">=</span> <span class="k">enum</span>
    <span class="n">Red</span> <span class="o">=</span> <span class="mh">0xFF0000</span><span class="p">,</span> <span
                class="n">Orange</span> <span class="o">=</span> <span class="mh">0xFFA500</span><span
                class="p">,</span> <span class="n">Yellow</span> <span class="o">=</span> <span
                class="mh">0xFFFF00</span>

  <span class="n">Signals</span> <span class="o">=</span> <span class="k">enum</span>
    <span class="n">sigQuit</span> <span class="o">=</span> <span class="mi">3</span><span class="p">,</span> <span
                class="n">sigAbort</span> <span class="o">=</span> <span class="mi">6</span><span
                class="p">,</span> <span class="n">sigKill</span> <span class="o">=</span> <span class="mi">9</span>

<span class="c"># echo Red  # Error: ambiguous identifier: 'Red'</span>
<span class="n">echo</span> <span class="n">Colors</span><span class="p">.</span><span class="n">Red</span>
<span class="n">echo</span> <span class="n">OtherColors</span><span class="p">.</span><span class="n">Red</span>
<span class="n">echo</span> <span class="n">OtherColors</span><span class="p">.</span><span class="n">Orange</span><span
                class="p">,</span> <span class="s">" "</span><span class="p">,</span> <span
                class="n">Orange</span></code></pre>

    <pre><code class="language-console"><span class="gp">$</span> nim c -r enumdefs.nim
<span class="go">FF0000</span>
<span class="go">Red</span>
<span class="go">Orange Orange</span></code></pre>

    <p>Notice that each element in <code>CompassDirections</code> is prepended with <code>cd</code> to avoid name
        conflicts since references to the enum value do not need to be qualified.</p>

    <p>The <code>{.pure.}</code> pragma that <code>Colors</code> and <code>OtherColors</code> have requires that all
        ambigious references to the enums’ values be qualified. This mean that <code>Orange</code> can be referred to
        without <code>OtherColors.Orange</code> (although <code>OtherColors.Orange</code> is still allowed).</p>

    <p>Enums can be given custom values and stringify values, as shown by <code>Colors</code> and <code>Signals</code>.
    </p>

    <h2 id="ordinals">Ordinals</h2>

    <p>While enums can also have disjoint values, it should not be used for any other reason than compatibility with C
        because it breaks the idea that enums are ordinal.</p>

    <pre><code class="language-nimrod"><span class="k">for</span> <span class="n">direction</span> <span
            class="ow">in</span> <span class="n">ord</span><span class="p">(</span><span class="n">low</span><span
            class="p">(</span><span class="n">CompassDirections</span><span class="p">))..</span>
                 <span class="n">ord</span><span class="p">(</span><span class="n">high</span><span
                class="p">(</span><span class="n">CompassDirections</span><span class="p">)):</span>
  <span class="n">echo</span> <span class="n">CompassDirections</span><span class="p">(</span><span
                class="n">direction</span><span class="p">),</span> <span class="s">" ord: "</span><span
                class="p">,</span> <span class="n">direction</span>

<span class="kd">var</span> <span class="n">ordinal</span> <span class="o">=</span> <span class="n">low</span><span
                class="p">(</span><span class="kt">int</span><span class="p">)</span>
<span class="n">inc</span> <span class="n">ordinal</span>
<span class="n">dec</span> <span class="n">ordinal</span>
<span class="n">echo</span> <span class="n">high</span><span class="p">(</span><span class="kt">char</span><span
                class="p">)</span></code></pre>
    <pre><code class="language-console"><span class="gp">$</span> nim c -r enums.nim
<span class="go">cdNorth ord: 0</span>
<span class="go">cdEast ord: 1</span>
<span class="go">cdSouth ord: 2</span>
<span class="go">cdWest ord: 3</span>
<span class="go">3</span>
<span class="go">�</span></code></pre>

    <p>Because enums are ordinals, they have the <code>low</code>, <code>high</code>, <code>inc</code>, <code>dec</code>,
        and <code>ord</code> methods defined, where</p>

    <ul>
        <li>
            <code>low</code> gives the lowest possible value
        </li>
        <li>
            <code>high</code> give the highest possible value
        </li>
        <li>
            <code>inc</code> increments
        </li>
        <li>
            <code>dec</code> decrements
        </li>
        <li>
            <code>ord</code> gives the integer value of the enum
        </li>
        <li>
            <code>CompassDirections</code> is a cast that gives an enum from an integer
        </li>
    </ul>

    <p>It is also possible to iterate through all possible values of ordinal enums, either as shown above, or <code>cdNorth..cdWest</code>,
        which is equivalent.</p>

    <pre><code class="language-nimrod"><span class="k">when</span> <span class="kp">false</span><span class="p">:</span>
  <span class="kd">var</span> <span class="n">nonOrdinal</span> <span class="o">=</span> <span class="n">sigQuit</span>
  <span class="n">inc</span> <span class="n">nonOrdinal</span>
  <span class="n">dec</span> <span class="n">nonOrdinal</span></code></pre>

    <p><code>Signals</code> is not an ordinal type, and so doesn’t have the <code>inc</code> and <code>dec</code>
        procedures.</p>

</article>

<div id=nextprev>
    <a class="text-icon disabled" href="https://please-enable-js/" id=arrow-prev>↽</a>
    <a class="text-icon disabled" href="https://please-enable-js/" id=arrow-next>⇁</a>
</div>

<footer>
    <li><a href="https://github.com/flaviut/nim-by-example">Contribute</a></li>
    <li
    ><a href="#" onclick="toggleDarkMode(); return false;">Toggle dark mode</a></li>

</footer>
</body>
</html>
